import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_ability/framework/http/adapter/hi_net_adapter.dart';
import 'package:flutter_ability/framework/http/request/base_request.dart';
import 'package:flutter_ability/framework/http/response/hi_error.dart';
import 'package:flutter_ability/framework/http/response/hi_response.dart';

/// dio 适配器
class DioAdapter extends HiNetAdapter {
  /// 发起请求
  Future<HiResponse<T>> send<T>(BaseRequest request, HttpMethod method) async {
    var options = Options(headers: request.header);
    Response? response;
    dynamic error;
    try {
      Dio dio = Dio();
      if (kDebugMode) {
        dio.interceptors
            .add(LogInterceptor(requestBody: true, responseBody: true));
      }
      switch (method) {
        case HttpMethod.GET:
          response = await dio.get(request.url(), options: options);
          break;
        case HttpMethod.POST:
          response = await dio.post(request.url(),
              data: request.params, options: options);
          break;
        case HttpMethod.DELETE:
          response = await dio.delete(request.url(),
              data: request.params, options: options);
          break;
      }
    } on DioError catch (e) {
      error = e;
      response = e.response;
    }

    /// 抛出HiNetError
    if (error != null) {
      throw HiError(response?.statusCode ?? -1, error.toString(),
          data: await buildRes(response, request));
    }
    return buildRes(response, request);
  }

  /// 构建HiNetResponse
  Future<HiResponse<T>> buildRes<T>(Response? response, BaseRequest request) {
    return Future.value(
      HiResponse(
        data: response?.data,
        request: request,
        statusCode: response?.statusCode,
        statusMessage: response?.statusMessage,
        extra: response,
      ),
    );
  }

  @override
  Future<HiResponse<T>> delete<T>(BaseRequest request) {
    return send(request, HttpMethod.DELETE);
  }

  @override
  Future<HiResponse<T>> get<T>(BaseRequest request) {
    return send(request, HttpMethod.GET);
  }

  @override
  Future<HiResponse<T>> post<T>(BaseRequest request) {
    return send(request, HttpMethod.POST);
  }
}
